home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / daemons / arpd / RCS / arpd.c,v < prev    next >
Encoding:
Text File  |  1992-06-17  |  29.2 KB  |  1,211 lines

  1. head     1.5;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.5
  10. date     92.06.16.21.17.19;  author jhh;  state Exp;
  11. branches ;
  12. next     1.4;
  13.  
  14. 1.4
  15. date     90.01.03.09.50.51;  author ouster;  state Exp;
  16. branches ;
  17. next     1.3;
  18.  
  19. 1.3
  20. date     90.01.02.17.38.34;  author ouster;  state Exp;
  21. branches ;
  22. next     1.2;
  23.  
  24. 1.2
  25. date     89.12.14.16.59.27;  author ouster;  state Exp;
  26. branches ;
  27. next     1.1;
  28.  
  29. 1.1
  30. date     89.11.28.10.54.32;  author ouster;  state Exp;
  31. branches ;
  32. next     ;
  33.  
  34.  
  35. desc
  36. @@
  37.  
  38.  
  39. 1.5
  40. log
  41. @port to new Host library
  42. uses standard Net stuff
  43. @
  44. text
  45. @/* 
  46.  * arpd.c --
  47.  *
  48.  *    A program to reply to ARP and RARP requests.  This program
  49.  *    only translates between Internet and Ethernet addresses.  See
  50.  *    RFC826 for details of the ARP protocol, and RFC903 for details
  51.  *    of the RARP protocol.
  52.  *
  53.  * Copyright 1989 Regents of the University of California
  54.  * Permission to use, copy, modify, and distribute this
  55.  * software and its documentation for any purpose and without
  56.  * fee is hereby granted, provided that the above copyright
  57.  * notice appear in all copies.  The University of California
  58.  * makes no representations about the suitability of this
  59.  * software for any purpose.  It is provided "as is" without
  60.  * express or implied warranty.
  61.  */
  62.  
  63. #ifndef lint
  64. static char rcsid[] = "$Header: /sprite/src/daemons/arpd/RCS/arpd.c,v 1.4 90/01/03 09:50:51 ouster Exp Locker: jhh $ SPRITE (Berkeley)";
  65. #endif not lint
  66.  
  67.  
  68. #include <stdio.h>
  69. #include <stdlib.h>
  70. #include <string.h>
  71. #include <errno.h>
  72. #include <host.h>
  73. #include <option.h>
  74. #include <sys/socket.h>
  75. #include <net/if_arp.h>
  76. #include <netinet/if_ether.h>
  77. #include <netinet/in.h>
  78. #include <sys/file.h>
  79. #include <sys/param.h>
  80. #include <sys/stat.h>
  81. #include <sys/time.h>
  82. #include <sys/types.h>
  83.  
  84. /*
  85.  * Command line options.
  86.  */
  87.  
  88. static int verbose = 0;
  89. static char *hostFile = NULL;
  90.  
  91. static Option optionArray[] = {
  92.     {OPT_TRUE,   "v", (char *) &verbose, "Turn on informational output"},
  93.     {OPT_STRING, "f", (char *) &hostFile, "Name of host database file"},
  94. };
  95. static int numOptions = sizeof(optionArray) / sizeof(Option);
  96.  
  97. /*
  98.  * One structure of the following type is created for each entry
  99.  * in the host table.  This saves us from having to regenerate the
  100.  * host table except when it changes.
  101.  */
  102.  
  103. typedef struct HostInfo {
  104.     char *name;            /* Textual name for this host. */
  105.     Net_InetAddress inetAddr;    /* Internet address for this host. */
  106.     Net_EtherAddress etherAddr;    /* Ethernet address for this host. */
  107.     struct HostInfo *nextPtr;    /* Next in list of all known hosts (NULL
  108.                  * for end of list). */
  109. } HostInfo;
  110.  
  111. HostInfo *hostList = NULL;    /* First in list of all known hosts. */
  112. int modTime = -1;        /* The information in memory corresponds to
  113.                  * this modify time on the host file. */
  114.  
  115. /*
  116.  * The ARP/RARP packet size is defined below.  Because of structure
  117.  * alignment differences between machines, it isn't safe to use
  118.  * sizeof with the structure.
  119.  */
  120.  
  121. #define ARP_PACKET_SIZE 42
  122.  
  123. /*
  124.  * The variable below holds the name of the host on which this program
  125.  * is running, and a pointer to the corresponding entry from the hosts
  126.  * file (NULL means no corresponding entry could be found in the hosts
  127.  * file).
  128.  */
  129.  
  130. char myName[MAXHOSTNAMELEN+1];
  131. HostInfo *myInfoPtr = NULL;
  132.  
  133. static void        DoArp();
  134. static void        DoRarp();
  135. static void        UpdateTable();
  136.  
  137. /*
  138.  *----------------------------------------------------------------------
  139.  *
  140.  * main --
  141.  *
  142.  *    The main loop of the ARP request handler. Packets are 
  143.  *    read from the netwok and examined to see if we can make a 
  144.  *    reply.
  145.  *
  146.  * Results:
  147.  *    None.
  148.  *
  149.  * Side effects:
  150.  *    None.
  151.  *
  152.  *----------------------------------------------------------------------
  153.  */
  154.  
  155. main(argc, argv)
  156.     int        argc;
  157.     char    **argv;
  158. {
  159.     int            arpID, rarpID;
  160.  
  161.     if (Opt_Parse(argc, argv,  optionArray, numOptions, 0) > 1) {
  162.     printf("arpd ignoring extra arguments\n");
  163.     }
  164.  
  165.     if (hostFile != NULL) {
  166.     if (Host_SetFile(hostFile)) {
  167.         perror("arpd couldn't set host file to \"%s\"", hostFile);
  168.         exit(1);
  169.     }
  170.     }
  171.  
  172.     /*
  173.      * Open the network devices, and read in the host database.  If
  174.      * either of these fails, then just quit right now.
  175.      */
  176.  
  177.     arpID = open("/dev/etherARP", O_RDWR, 0600); 
  178.     if (arpID < 0) {
  179.     perror("arpd couldn't open /dev/etherARP");
  180.     exit(1);
  181.     }
  182.     rarpID = open("/dev/etherRARP", O_RDWR, 0600); 
  183.     if (rarpID < 0) {
  184.     perror("arpd couldn't open /dev/etherRARP");
  185.     exit(1);
  186.     }
  187.     if (gethostname(myName, MAXHOSTNAMELEN+1) < 0) {
  188.     perror("arpd couldn't get host name from gethostname()");
  189.     exit(1);
  190.     }
  191.     UpdateTable();
  192.     if (modTime == -1) {
  193.     exit(1);
  194.     }
  195.  
  196.     /*
  197.      * Enter an infinite loop servicing ARP and RARP requests.
  198.      */
  199.  
  200.     while (1) {
  201.     int readMask, numReady;
  202.  
  203.     readMask = (1 << arpID) | (1 << rarpID);
  204.     numReady = select(rarpID+1, &readMask, (int *) NULL,
  205.         (int *) NULL, (struct timeval *) NULL);
  206.     if ((numReady < 0) && (errno != EINTR)) {
  207.         printf("arpd couldn't select on network devices: %s\n",
  208.             strerror(errno));
  209.         exit(1);
  210.     }
  211.  
  212.     if (readMask & (1 << arpID)) {
  213.         DoArp(arpID);
  214.     }
  215.     if (readMask & (1 << rarpID)) {
  216.         DoRarp(rarpID);
  217.     }
  218.     }
  219. }
  220.  
  221. /*
  222.  *----------------------------------------------------------------------
  223.  *
  224.  * DoArp --
  225.  *
  226.  *    Handle an ARP request.
  227.  *
  228.  * Results:
  229.  *    None.
  230.  *
  231.  * Side effects:
  232.  *    A response is transmitted for the ARP request.
  233.  *
  234.  *----------------------------------------------------------------------
  235.  */
  236.  
  237. static void
  238. DoArp(streamID)
  239.     int streamID;        /* Integer stream # for ARP device. */
  240. {
  241.     struct {
  242.     struct ether_header hdr;
  243.     struct ether_arp arp;
  244.     } packet;
  245.     int bytesRead, bytesWritten, etherType, protocolType, hardwareType, arpOp;
  246.     unsigned long senderAddr, targetAddr;
  247.     register HostInfo *infoPtr;
  248.  
  249.     /*
  250.      * Read and validate the ARP packet.
  251.      */
  252.  
  253.     bytesRead = read(streamID, (char *) &packet, ARP_PACKET_SIZE);
  254.     if (bytesRead < 0) {
  255.     printf("arpd couldn't read ARP packet: %s\n",
  256.         strerror(errno));
  257.     return;
  258.     }
  259.     if (bytesRead < ARP_PACKET_SIZE) {
  260.     printf("arpd got short ARP packet: only %d bytes\n",
  261.         bytesRead);
  262.     return;
  263.     }
  264.     etherType = ntohs(packet.hdr.ether_type);
  265.     if (etherType != ETHERTYPE_ARP) {
  266.     printf("arpd got ARP packet with ether_type 0x%x\n",
  267.         etherType);
  268.     return;
  269.     }
  270.     arpOp = ntohs(packet.arp.ea_hdr.ar_op);
  271.     if (arpOp != ARPOP_REQUEST) {
  272.     if (verbose) {
  273.         printf("arpd got ARP packet with unknown op %d\n",
  274.             arpOp);
  275.     }
  276.     return;
  277.     }
  278.     hardwareType = ntohs(packet.arp.ea_hdr.ar_hrd);
  279.     if (hardwareType != ARPHRD_ETHER) {
  280.     if (verbose) {
  281.         printf("arpd got ARP packet with unknown hardware type 0x%x\n",
  282.             hardwareType);
  283.     }
  284.     return;
  285.     }
  286.     protocolType = ntohs(packet.arp.ea_hdr.ar_pro);
  287.     if (protocolType != ETHERTYPE_IP) {
  288.     if (verbose) {
  289.         printf("arpd got ARP packet with unknown protocol type 0x%x\n",
  290.             protocolType);
  291.     }
  292.     return;
  293.     }
  294.     UpdateTable();
  295.  
  296.     /*
  297.      * Look for an entry in our host database that matches the given
  298.      * protocol address.  The bcopy calls below are needed because
  299.      * integers may not be properly aligned in the packet.
  300.      */
  301.  
  302.     bcopy((char *) packet.arp.arp_spa, (char *) &senderAddr,
  303.         sizeof(senderAddr));
  304.     bcopy((char *) packet.arp.arp_tpa, (char *) &targetAddr,
  305.         sizeof(targetAddr));
  306.     if (verbose) {
  307.     struct timeval time;
  308.     char *string;
  309.     char buffer1[32];
  310.     char buffer2[32];
  311.  
  312.     gettimeofday(&time, (struct timezone *) NULL);
  313.     string = ctime(&time.tv_sec);
  314.     string[24] = 0;
  315.     printf("ARP at %s from %s for %s", string, 
  316.         Net_InetAddrToString(senderAddr, buffer1), 
  317.         Net_InetAddrToString(targetAddr, buffer2));
  318.     }
  319.     for (infoPtr = hostList; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {
  320.     if (infoPtr->inetAddr == targetAddr) {
  321.         break;
  322.     }
  323.     }
  324.     if (infoPtr == NULL) {
  325.     if (verbose) {
  326.         printf(": unknown target\n");
  327.     }
  328.     return;
  329.     }
  330.     if (verbose) {
  331.     char    buffer[20];
  332.     printf(": %s\n", Net_EtherAddrToString(&infoPtr->etherAddr, buffer));
  333.     }
  334.  
  335.     /*
  336.      * Reverse sender and target fields, and respond with the appropriate
  337.      * Ethernet address.  No need to fill in the source in the packet
  338.      * header:  the kernel automatically overwrites it.
  339.      */
  340.  
  341.     bcopy((char *) &targetAddr, (char *) packet.arp.arp_spa,
  342.         sizeof(targetAddr));
  343.     bcopy((char *) &senderAddr, (char *) packet.arp.arp_tpa,
  344.         sizeof(senderAddr));
  345.     bcopy((char *) packet.arp.arp_sha, (char *) packet.arp.arp_tha,
  346.         sizeof(Net_EtherAddress));
  347.     bcopy((char *) &infoPtr->etherAddr, (char *) packet.arp.arp_sha,
  348.         sizeof(Net_EtherAddress));
  349.     packet.arp.ea_hdr.ar_op = htons(ARPOP_REPLY);
  350.     bcopy((char *) packet.hdr.ether_shost, (char *) packet.hdr.ether_dhost,
  351.         sizeof(Net_EtherAddress));
  352.     bytesWritten = write(streamID, (char *) &packet, ARP_PACKET_SIZE);
  353.     if (bytesWritten < 0) {
  354.     printf("arpd couldn't send ARP response: %s\n",
  355.         strerror(errno));
  356.     return;
  357.     }
  358.     if (bytesWritten != ARP_PACKET_SIZE) {
  359.     printf("arpd short write of ARP response: %d bytes\n",
  360.         bytesWritten);
  361.     return;
  362.     }
  363. }
  364.  
  365. /*
  366.  *----------------------------------------------------------------------
  367.  *
  368.  * DoRarp --
  369.  *
  370.  *    Handle a RARP request.
  371.  *
  372.  * Results:
  373.  *    None.
  374.  *
  375.  * Side effects:
  376.  *    A response is transmitted for the RARP request.
  377.  *
  378.  *----------------------------------------------------------------------
  379.  */
  380.  
  381. static void
  382. DoRarp(streamID)
  383.     int streamID;        /* Integer stream # for ARP device. */
  384. {
  385.     struct {
  386.     struct ether_header hdr;
  387.     struct ether_arp arp;
  388.     } packet;
  389.     int bytesRead, bytesWritten, etherType, protocolType, hardwareType, arpOp;
  390.     unsigned long senderAddr, targetAddr;
  391.     register HostInfo *infoPtr;
  392.  
  393.     /*
  394.      * Read and validate the ARP packet.
  395.      */
  396.  
  397.     bytesRead = read(streamID, (char *) &packet, ARP_PACKET_SIZE);
  398.     if (bytesRead < 0) {
  399.     printf("arpd couldn't read RARP packet: %s\n",
  400.         strerror(errno));
  401.     return;
  402.     }
  403.     if (bytesRead < ARP_PACKET_SIZE) {
  404.     printf("arpd got short RARP packet: only %d bytes\n",
  405.         bytesRead);
  406.     return;
  407.     }
  408.     etherType = ntohs(packet.hdr.ether_type);
  409.     if (etherType != ETHERTYPE_RARP) {
  410.     printf("arpd got ARP packet with ether_type 0x%x\n",
  411.         etherType);
  412.     return;
  413.     }
  414.     arpOp = ntohs(packet.arp.ea_hdr.ar_op);
  415.     if (arpOp != REVARP_REQUEST) {
  416.     if (verbose) {
  417.         printf("arpd got RARP packet with unknown op %d\n", arpOp);
  418.     }
  419.     return;
  420.     }
  421.     hardwareType = ntohs(packet.arp.ea_hdr.ar_hrd);
  422.     if (hardwareType != ARPHRD_ETHER) {
  423.     if (verbose) {
  424.         printf("arpd got RARP packet with unknown hardware type 0x%x\n",
  425.             hardwareType);
  426.     }
  427.     return;
  428.     }
  429.     protocolType = ntohs(packet.arp.ea_hdr.ar_pro);
  430.     if (protocolType != ETHERTYPE_IP) {
  431.     if (verbose) {
  432.         printf("arpd got RARP packet with unknown protocol type 0x%x\n",
  433.             protocolType);
  434.     }
  435.     return;
  436.     }
  437.     UpdateTable();
  438.  
  439.     /*
  440.      * Look for an entry in our host database that matches the given
  441.      * protocol address.  The bcopy calls below are needed because
  442.      * integers may not be properly aligned in the packet.
  443.      */
  444.  
  445.     if (verbose) {
  446.     struct timeval time;
  447.     char *string;
  448.     char ether1[20];
  449.     char ether2[20];
  450.  
  451.     gettimeofday(&time, (struct timezone *) NULL);
  452.     string = ctime(&time.tv_sec);
  453.     string[24] = 0;
  454.     printf("RARP at %s from %s for %s", string, 
  455.         Net_EtherAddrToString((Net_EtherAddress *) packet.arp.arp_sha,
  456.             ether1),
  457.         Net_EtherAddrToString((Net_EtherAddress *) packet.arp.arp_tha,
  458.             ether2));
  459.     }
  460.     for (infoPtr = hostList; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {
  461.     if (Net_EtherAddrCmpPtr((Net_EtherAddress *) packet.arp.arp_sha, 
  462.         &infoPtr->etherAddr) == 0) {
  463.         break;
  464.     }
  465.     }
  466.     if (infoPtr == NULL) {
  467.     if (verbose) {
  468.         printf(": unknown target\n");
  469.     }
  470.     return;
  471.     }
  472.     targetAddr = infoPtr->inetAddr;
  473.     if (verbose) {
  474.     char    inet[32];
  475.     printf(": %s\n", Net_InetAddrToString((Net_InetAddress) targetAddr,
  476.             inet));
  477.     }
  478.  
  479.     /*
  480.      * Reverse sender and target fields, and respond with the appropriate
  481.      * Internet address.  No need to fill in the source in the packet
  482.      * header:  the kernel automatically overwrites it.
  483.      */
  484.  
  485.     bcopy((char *) packet.arp.arp_sha, (char *) packet.arp.arp_tha,
  486.         sizeof(Net_EtherAddress));
  487.     bcopy((char *) &targetAddr, (char *) packet.arp.arp_tpa,
  488.         sizeof(targetAddr));
  489.     if (myInfoPtr != NULL) {
  490.     bcopy((char *) &myInfoPtr->etherAddr, (char *) packet.arp.arp_sha,
  491.         sizeof(Net_EtherAddress));
  492.     senderAddr = myInfoPtr->inetAddr;
  493.     bcopy((char *) &senderAddr, (char *) packet.arp.arp_spa,
  494.         sizeof(senderAddr));
  495.     } else {
  496.     bzero((char *) packet.arp.arp_sha, sizeof(Net_EtherAddress));
  497.     bzero((char *) packet.arp.arp_spa, sizeof(senderAddr));
  498.     }
  499.     packet.arp.ea_hdr.ar_op = htons(REVARP_REPLY);
  500.     bcopy((char *) packet.hdr.ether_shost, (char *) packet.hdr.ether_dhost,
  501.         sizeof(Net_EtherAddress));
  502.     bytesWritten = write(streamID, (char *) &packet, ARP_PACKET_SIZE);
  503.     if (bytesWritten < 0) {
  504.     printf("arpd couldn't send RARP response: %s\n",
  505.         strerror(errno));
  506.     return;
  507.     }
  508.     if (bytesWritten != ARP_PACKET_SIZE) {
  509.     printf("arpd short write of RARP response: %d bytes\n",
  510.         bytesWritten);
  511.     return;
  512.     }
  513. }
  514.  
  515. /*
  516.  *----------------------------------------------------------------------
  517.  *
  518.  * UpdateTable --
  519.  *
  520.  *    Make sure that the host information in memory is up-to-date.
  521.  *    If not, throw away what we've got and read in fresh stuff.
  522.  *
  523.  * Results:
  524.  *    None.
  525.  *
  526.  * Side effects:
  527.  *    The information in the list pointed to by hostList is
  528.  *    potentially modified, as is the modTime variable.  The pointer
  529.  *    myInfoPtr is (re-)set to point to the information for the
  530.  *    host named "myName".
  531.  *
  532.  *----------------------------------------------------------------------
  533.  */
  534.  
  535. static void
  536. UpdateTable()
  537. {
  538.     struct stat buf;
  539.     register HostInfo *infoPtr;
  540.     register Host_Entry *hostPtr;
  541.     int            i;
  542.     ReturnStatus    status;
  543.  
  544.     /*
  545.      * See if the current database is up-to-date.  If so,
  546.      * then just return.
  547.      */
  548.  
  549.     if (Host_Stat(&buf) != 0) {
  550.     printf("arpd couldn't stat host file: %s\n", strerror(errno));
  551.     return;
  552.     }
  553.     if (buf.st_mtime == modTime) {
  554.     return;
  555.     }
  556.  
  557.     /*
  558.      * Throw away everything that's currently in memory.
  559.      */
  560.  
  561.     while (hostList != NULL) {
  562.     infoPtr = hostList;
  563.     hostList = infoPtr->nextPtr;
  564.     free(infoPtr->name);
  565.     free((char *) infoPtr);
  566.     }
  567.  
  568.     /*
  569.      * Rebuild the database from the host database file.
  570.      */
  571.  
  572.     if (verbose) {
  573.     char *timeString;
  574.     timeString = ctime(&buf.st_mtime);
  575.     timeString[24] = 0;
  576.     printf("arpd reloading database from host file (modified %s)\n",
  577.         timeString);
  578.     }
  579.  
  580.     if (Host_Start() != 0) {
  581.     printf("arpd: Host_Start failed : %s\n", strerror(errno));
  582.     return;
  583.     }
  584.  
  585.     myInfoPtr = NULL;
  586.     for (hostPtr = Host_Next(); hostPtr != NULL; hostPtr = Host_Next()) {
  587.     for (i = 0; i < hostPtr->numNets; i++) {
  588.         if (hostPtr->nets[i].netAddr.type == NET_ADDRESS_ETHER) {
  589.         infoPtr = (HostInfo *) malloc(sizeof(HostInfo));
  590.         infoPtr->name = malloc((unsigned) (strlen(hostPtr->name) + 1));
  591.         strcpy(infoPtr->name, hostPtr->name);
  592.         infoPtr->inetAddr = hostPtr->nets[i].inetAddr;
  593.         status = Net_GetAddress(&hostPtr->nets[i].netAddr, 
  594.                 &infoPtr->etherAddr);
  595.         if (status != SUCCESS) {
  596.             printf("arpd: Net_GetAddress failed\n");
  597.             goto done;
  598.         }
  599.         infoPtr->nextPtr = hostList;
  600.         hostList = infoPtr;
  601.         if (strcmp(myName, infoPtr->name) == 0) {
  602.             myInfoPtr = infoPtr;
  603.         }
  604.         break;
  605.         }
  606.     }
  607.     }
  608. done:
  609.     Host_End();
  610.     modTime = buf.st_mtime;
  611. }
  612. @
  613.  
  614.  
  615. 1.4
  616. log
  617. @Lint cleanup and make all messages go to stdout.
  618. @
  619. text
  620. @d20 1
  621. a20 1
  622. static char rcsid[] = "$Header: /sprite/src/daemons/arpd/RCS/arpd.c,v 1.3 90/01/02 17:38:34 ouster Exp Locker: ouster $ SPRITE (Berkeley)";
  623. d45 1
  624. a45 1
  625. static char *hostFile = "/etc/spritehosts";
  626. d61 2
  627. a62 3
  628.     unsigned long inetAddr;    /* Internet address for this host. */
  629.     unsigned char etherAddr[HOST_ETHER_ADDRESS_SIZE];
  630.                 /* Ethernet address for this host. */
  631. d121 7
  632. a259 1
  633.     senderAddr = ntohl((unsigned long) senderAddr);
  634. a261 1
  635.     targetAddr = ntohl(targetAddr);
  636. d265 2
  637. d271 3
  638. a273 5
  639.     printf("ARP at %s from %d.%d.%d.%d for %d.%d.%d.%d", string,
  640.         (senderAddr >> 24) & 0xff, (senderAddr >> 16) & 0xff,
  641.         (senderAddr >> 8) & 0xff, senderAddr & 0xff,
  642.         (targetAddr >> 24) & 0xff, (targetAddr >> 16) & 0xff,
  643.         (targetAddr >> 8) & 0xff, targetAddr & 0xff);
  644. d287 2
  645. a288 4
  646.     printf(": %x:%x:%x:%x:%x:%x\n",
  647.         infoPtr->etherAddr[0], infoPtr->etherAddr[1],
  648.         infoPtr->etherAddr[2], infoPtr->etherAddr[3],
  649.         infoPtr->etherAddr[4], infoPtr->etherAddr[5]);
  650. a296 1
  651.     targetAddr = htonl(targetAddr);
  652. a298 1
  653.     senderAddr = htonl(senderAddr);
  654. d302 3
  655. a304 3
  656.         HOST_ETHER_ADDRESS_SIZE);
  657.     bcopy((char *) infoPtr->etherAddr, (char *) packet.arp.arp_sha,
  658.         HOST_ETHER_ADDRESS_SIZE);
  659. d307 1
  660. a307 1
  661.         HOST_ETHER_ADDRESS_SIZE);
  662. d404 2
  663. d410 5
  664. a414 8
  665.     printf("RARP at %s from %x:%x:%x:%x:%x:%x for %x:%x:%x:%x:%x:%x",
  666.         string,
  667.         packet.arp.arp_sha[0], packet.arp.arp_sha[1],
  668.         packet.arp.arp_sha[2], packet.arp.arp_sha[3],
  669.         packet.arp.arp_sha[4], packet.arp.arp_sha[5],
  670.         packet.arp.arp_tha[0], packet.arp.arp_tha[1],
  671.         packet.arp.arp_tha[2], packet.arp.arp_tha[3],
  672.         packet.arp.arp_tha[4], packet.arp.arp_tha[5]);
  673. d417 2
  674. a418 6
  675.     if ((packet.arp.arp_sha[5] == infoPtr->etherAddr[5])
  676.         && (packet.arp.arp_sha[4] == infoPtr->etherAddr[4])
  677.         && (packet.arp.arp_sha[3] == infoPtr->etherAddr[3])
  678.         && (packet.arp.arp_sha[2] == infoPtr->etherAddr[2])
  679.         && (packet.arp.arp_sha[1] == infoPtr->etherAddr[1])
  680.         && (packet.arp.arp_sha[0] == infoPtr->etherAddr[0])) {
  681. d430 3
  682. a432 3
  683.     printf(": %d.%d.%d.%d\n",
  684.         (targetAddr >> 24) & 0xff, (targetAddr >> 16) & 0xff,
  685.         (targetAddr >> 8) & 0xff, targetAddr & 0xff);
  686. d442 1
  687. a442 2
  688.         HOST_ETHER_ADDRESS_SIZE);
  689.     targetAddr = htonl(targetAddr);
  690. d446 3
  691. a448 3
  692.     bcopy((char *) myInfoPtr->etherAddr, (char *) packet.arp.arp_sha,
  693.         HOST_ETHER_ADDRESS_SIZE);
  694.     senderAddr = htonl(myInfoPtr->inetAddr);
  695. d452 1
  696. a452 1
  697.     bzero((char *) packet.arp.arp_sha, HOST_ETHER_ADDRESS_SIZE);
  698. d457 1
  699. a457 1
  700.         HOST_ETHER_ADDRESS_SIZE);
  701. d497 2
  702. d505 2
  703. a506 2
  704.     if (stat(hostFile, &buf) != 0) {
  705.     printf("arpd couldn't stat \"%s\": %s\n", hostFile, strerror(errno));
  706. d532 2
  707. a533 2
  708.     printf("arpd reloading database from \"%s\" (modified %s)\n",
  709.         hostFile, timeString);
  710. d536 2
  711. a537 2
  712.     if (Host_SetFile(hostFile) != 0) {
  713.     printf("arpd couldn't access \"%s\" : %s", hostFile, strerror(errno));
  714. d543 18
  715. a560 11
  716.     if (hostPtr->netType == HOST_ETHER) {
  717.         infoPtr = (HostInfo *) malloc(sizeof(HostInfo));
  718.         infoPtr->name = malloc((unsigned) (strlen(hostPtr->name) + 1));
  719.         strcpy(infoPtr->name, hostPtr->name);
  720.         infoPtr->inetAddr = *((int *) &hostPtr->inetAddr);
  721.         bcopy((char *) hostPtr->netAddr.etherAddr,
  722.             (char *) infoPtr->etherAddr, HOST_ETHER_ADDRESS_SIZE);
  723.         infoPtr->nextPtr = hostList;
  724.         hostList = infoPtr;
  725.         if (strcmp(myName, infoPtr->name) == 0) {
  726.         myInfoPtr = infoPtr;
  727. d564 1
  728. @
  729.  
  730.  
  731. 1.3
  732. log
  733. @Added RARP protocol.
  734. @
  735. text
  736. @d20 1
  737. a20 1
  738. static char rcsid[] = "$Header: /sprite/src/daemons/arpd/RCS/arpd.c,v 1.2 89/12/14 16:59:27 ouster Exp $ SPRITE (Berkeley)";
  739. d61 1
  740. a61 1
  741.     int inetAddr;        /* Internet address for this host. */
  742. d119 1
  743. a119 1
  744.     fprintf(stderr, "arpd ignoring extra arguments\n");
  745. d157 1
  746. a157 1
  747.         fprintf(stderr, "arpd couldn't select on network devices: %s\n",
  748. d196 1
  749. a196 2
  750.     int senderAddr, targetAddr;
  751.     short shortTmp;
  752. d205 1
  753. a205 1
  754.     fprintf(stderr, "arpd couldn't read ARP packet: %s\n",
  755. d210 1
  756. a210 1
  757.     fprintf(stderr, "arpd got short ARP packet: only %d bytes\n",
  758. d216 1
  759. a216 1
  760.     fprintf(stderr, "arpd got ARP packet with ether_type 0x%x\n",
  761. d222 4
  762. a225 2
  763.     fprintf(stderr, "arpd got ARP packet with unknown op %d\n",
  764.         arpOp);
  765. d230 4
  766. a233 2
  767.     fprintf(stderr, "arpd got ARP packet with unknown hardware type 0x%x\n",
  768.         hardwareType);
  769. d238 4
  770. a241 2
  771.     fprintf(stderr, "arpd got ARP packet with unknown protocol type 0x%x\n",
  772.         protocolType);
  773. d254 1
  774. a254 1
  775.     senderAddr = ntohl(senderAddr);
  776. d301 1
  777. a301 1
  778.     bcopy(packet.arp.arp_sha, packet.arp.arp_tha,
  779. d303 1
  780. a303 1
  781.     bcopy(infoPtr->etherAddr, packet.arp.arp_sha,
  782. d306 1
  783. a306 1
  784.     bcopy(packet.hdr.ether_shost, packet.hdr.ether_dhost,
  785. d308 1
  786. a308 1
  787.     bytesWritten = write(streamID, &packet, ARP_PACKET_SIZE);
  788. d310 1
  789. a310 1
  790.     fprintf(stderr, "arpd couldn't send ARP response: %s\n",
  791. d315 1
  792. a315 1
  793.     fprintf(stderr, "arpd short write of ARP response: %d bytes\n",
  794. d346 1
  795. a346 1
  796.     int senderAddr, targetAddr;
  797. a347 1
  798.     char tmp[HOST_ETHER_ADDRESS_SIZE];
  799. d355 1
  800. a355 1
  801.     fprintf(stderr, "arpd couldn't read RARP packet: %s\n",
  802. d360 1
  803. a360 1
  804.     fprintf(stderr, "arpd got short RARP packet: only %d bytes\n",
  805. d366 1
  806. a366 1
  807.     fprintf(stderr, "arpd got ARP packet with ether_type 0x%x\n",
  808. d372 3
  809. a374 2
  810.     fprintf(stderr, "arpd got RARP packet with unknown op %d\n",
  811.         arpOp);
  812. d379 4
  813. a382 3
  814.     fprintf(stderr,
  815.         "arpd got RARP packet with unknown hardware type 0x%x\n",
  816.         hardwareType);
  817. d387 4
  818. a390 3
  819.     fprintf(stderr,
  820.         "arpd got RARP packet with unknown protocol type 0x%x\n",
  821.         protocolType);
  822. d462 1
  823. a462 1
  824.     bcopy(packet.hdr.ether_shost, packet.hdr.ether_dhost,
  825. d464 1
  826. a464 1
  827.     bytesWritten = write(streamID, &packet, ARP_PACKET_SIZE);
  828. d466 1
  829. a466 1
  830.     fprintf(stderr, "arpd couldn't send RARP response: %s\n",
  831. d471 1
  832. a471 1
  833.     fprintf(stderr, "arpd short write of RARP response: %d bytes\n",
  834. d510 1
  835. a510 2
  836.     fprintf(stderr, "arpd couldn't stat \"%s\": %s\n",
  837.         hostFile, strerror(errno));
  838. d541 1
  839. a541 2
  840.     fprintf(stderr, "arpd couldn't access \"%s\" : %s",
  841.         hostFile, strerror(errno));
  842. @
  843.  
  844.  
  845. 1.2
  846. log
  847. @Showing some signs of life (ARP only, though).
  848. @
  849. text
  850. @d20 1
  851. a20 1
  852. static char rcsid[] = "$Header: /sprite/src/daemons/arpd/RCS/arpd.c,v 1.1 89/11/28 10:54:32 ouster Exp Locker: ouster $ SPRITE (Berkeley)";
  853. d35 1
  854. d80 10
  855. d137 4
  856. d156 1
  857. a156 1
  858.     if (numReady < 0) {
  859. d166 1
  860. a166 1
  861.         /* DoRarp(rarpID); */
  862. d187 1
  863. a187 1
  864. void
  865. d197 1
  866. d239 1
  867. d243 2
  868. a244 1
  869.      * protocol address.
  870. d247 6
  871. a252 2
  872.     senderAddr = ntohl(*((int*) packet.arp.arp_spa));
  873.     targetAddr = ntohl(*((int*) packet.arp.arp_tpa));
  874. d290 10
  875. a299 4
  876.     *((int *) packet.arp.arp_spa) = htonl(targetAddr);
  877.     *((int *) packet.arp.arp_tpa) = htonl(senderAddr);
  878.     bcopy(packet.arp.arp_sha, packet.arp.arp_tha, HOST_ETHER_ADDRESS_SIZE);
  879.     bcopy(infoPtr->etherAddr, packet.arp.arp_sha, HOST_ETHER_ADDRESS_SIZE);
  880. d319 154
  881. d483 3
  882. a485 1
  883.  *    potentially modified, as is the modTime variable.
  884. d540 1
  885. d547 1
  886. a547 1
  887.         bcopy((char *) &hostPtr->netAddr.etherAddr,
  888. d551 3
  889. @
  890.  
  891.  
  892. 1.1
  893. log
  894. @Initial revision
  895. @
  896. text
  897. @d2 1
  898. a2 1
  899.  * rarp.c --
  900. d4 4
  901. a7 1
  902.  *    A program to reply to RARP requests. 
  903. d20 1
  904. a20 1
  905. static char rcsid[] = "$Header: /sprite/users/reeves/rarp/rarp/RCS/rarp.c,v 1.7 89/04/05 15:46:57 reeves Exp $ SPRITE (Berkeley)";
  906. d25 1
  907. a27 2
  908. #include <sprite.h>
  909. #include <net.h>
  910. a28 3
  911. #include <fs.h>
  912. #include <proc.h>
  913. #include <hash.h>
  914. d30 4
  915. d36 1
  916. a37 1
  917. #include <sys/param.h>
  918. d43 2
  919. a44 2
  920. static Boolean debug = FALSE;
  921. static char *hostFile = (char *)NULL;
  922. d47 2
  923. a48 2
  924.     {OPT_TRUE,   "d", (Address)&debug, "Turn on debugging output"},
  925.     {OPT_STRING, "f", (Address)&hostFile, "Name of host database file"},
  926. d52 5
  927. d58 20
  928. a77 7
  929. static Hash_Table    table;
  930. static Boolean        firstInit = TRUE;
  931. static char        regHostFile[] = "/etc/spritehosts";
  932. static Boolean        UpdateModifyTime();
  933. static Boolean        Lookup();
  934. static void        InitTable();
  935. static void        EtherAddrCopy();
  936. d79 3
  937. a100 1
  938.  
  939. d105 4
  940. a108 23
  941.     int            streamID;
  942.     int            amt;
  943.     char        stringBuf[20];
  944.     char        hostName[MAXHOSTNAMELEN + 1];
  945.     Net_ArpPacket    packet;
  946.     Net_InetAddress     inetAddr;
  947.     Host_Entry         hostEntry;
  948.     time_t        lastModifyTime;
  949.  
  950.     if (sizeof(Net_ArpPacket) != 42) {
  951.     panic("RARP: RARP protocol header wrong size.\n");
  952.     }
  953.  
  954.     if (Opt_Parse(argc, argv,  optionArray, numOptions, 0) > 0) {
  955.     printf("Unknown arguments ignored\n");
  956.     }
  957.  
  958.     if (!debug) {
  959.     Proc_Detach(0);
  960.     }
  961.  
  962.     if (hostFile == (char *) NULL) {
  963.     hostFile = regHostFile;
  964. d111 13
  965. a123 3
  966.     streamID = open("/dev/etherRARP", O_RDWR, 0600); 
  967.     if (streamID < 0) {
  968.     perror("Couldn't open /dev/etherRARP");
  969. d126 2
  970. a127 4
  971.  
  972.     UpdateModifyTime(hostFile, &lastModifyTime);
  973.     if (gethostname(hostName, MAXHOSTNAMELEN + 1) < 0) {
  974.     perror("RARP - Couldn't get host name:");
  975. a129 4
  976.     bcopy ((char *)Host_ByName(hostName), (char *)&hostEntry,
  977.     (int)sizeof(Host_Entry));
  978.     InitTable(hostFile);
  979.     firstInit = FALSE;
  980. d131 13
  981. a143 4
  982.     while (TRUE) {
  983.     amt = read(streamID, (char *)&packet, sizeof(packet));
  984.     if (amt < 0) {
  985.         perror("Read error in RARP");
  986. d146 6
  987. a151 3
  988.     if (amt != sizeof(packet)) {
  989.         fprintf(stderr, "Warning: RARP: short read of packet: %d\n", amt);
  990.         continue;
  991. a152 49
  992.     if ((Net_NetToHostShort(packet.hardwareType) != NET_ARP_TYPE_ETHER) ||
  993.         (packet.hardwareAddrLen != sizeof(Net_EtherAddress))) { 
  994.         continue;
  995.     }
  996.     if ((Net_NetToHostShort(packet.protocolType) != NET_ETHER_IP) ||
  997.         (packet.opcode != NET_RARP_REQUEST)) {
  998.         continue;
  999.     }
  1000.     if (UpdateModifyTime(hostFile, &lastModifyTime) == TRUE) {
  1001.         (void)Hash_DeleteTable(&table);
  1002.         InitTable(hostFile);
  1003.         bcopy ((char *)Host_ByName(hostName), (char *)&hostEntry,
  1004.         (int)sizeof(Host_Entry));
  1005.     }
  1006.     if (!Lookup(&packet.targetEtherAddr, &inetAddr)) {
  1007.         continue;
  1008.     }
  1009.     if (debug == TRUE) {
  1010.         Net_EtherAddrToString(&packet.targetEtherAddr, stringBuf);
  1011.         printf("Request for RARP from ether: %s \n", stringBuf);
  1012.         Net_InetAddrToString(inetAddr, stringBuf);
  1013.         printf("...Responding with inet: %s \n\n", stringBuf);
  1014.     }
  1015.  
  1016.     /*
  1017.      * Create the reply packet, filling in needed data.
  1018.      */
  1019.  
  1020.     bcopy ((char *)&hostEntry.netAddr.etherAddr, 
  1021.         (char *)&packet.senderEtherAddr, (int)sizeof(Net_EtherAddress));
  1022.     packet.senderProtAddr = 
  1023.         *(Net_InetAddress *)&(hostEntry.inetAddr);
  1024.     packet.targetProtAddr = inetAddr;
  1025.     packet.opcode = Net_NetToHostShort(NET_RARP_REPLY);
  1026.  
  1027.     /*
  1028.      * The packet.header.source is filled by the kernel.
  1029.      */
  1030.     packet.header.destination = packet.header.source;
  1031.  
  1032.     amt = write(streamID, (char *)&packet, sizeof(packet));
  1033.     if (amt < 0) {
  1034.         perror("Failed write to /dev/etherRARP");
  1035.         exit(1);
  1036.     } 
  1037.     if (amt != sizeof(packet)) {
  1038.         fprintf(stderr,"Warning: RARP: short write of packet: %d\n",
  1039.             amt);
  1040.     } 
  1041. a154 1
  1042.  
  1043. a155 1
  1044.  
  1045. d159 1
  1046. a159 1
  1047.  * InitTable --
  1048. d161 1
  1049. a161 2
  1050.  *    Initializes the lookup table using the entries in the Host
  1051.  *    database 'configFile', if given.
  1052. d167 1
  1053. a167 1
  1054.  *    The hash table is initialzied and loaded with data.
  1055. d172 3
  1056. a174 3
  1057. static void
  1058. InitTable(configFile)
  1059.     char    *configFile;
  1060. d176 109
  1061. a284 27
  1062.     Host_Entry    *host;
  1063.     Hash_Entry    *entryPtr;
  1064.     Host_Entry    *newPtr;
  1065.     Boolean    newEntry;
  1066.     int        etherValue[2];
  1067.  
  1068.     /* We hash on 2 words because of Ethernet address length */
  1069.     Hash_InitTable(&table, 0, 2);
  1070.  
  1071.     if (Host_SetFile(configFile) != 0) {
  1072.     fprintf(stderr, "RARP couldn't access hostfile \"%s\" : %s",
  1073.         configFile, strerror(errno));
  1074.     exit(1);
  1075.     }
  1076.  
  1077.     while ((host = Host_Next()) != (Host_Entry *)NULL) {
  1078.     if (host->netType == HOST_ETHER) {
  1079.         newPtr = (Host_Entry *) malloc((unsigned)sizeof(Host_Entry));
  1080.         if (newPtr == (Host_Entry *) NULL) {     
  1081.         panic("RARP: Out of memory \n");
  1082.         }
  1083.         bcopy ((char *)host, (char *)newPtr, sizeof(Host_Entry));
  1084.         EtherAddrCopy(newPtr->netAddr.etherAddr, (short *)etherValue);
  1085.         entryPtr = Hash_CreateEntry(&table, (Address) etherValue,
  1086.             &newEntry);
  1087.         Hash_SetValue(entryPtr, (ClientData) &newPtr->inetAddr);
  1088.     }
  1089. a285 3
  1090.     if (debug) {
  1091.     printf("Done with initialization\n\n");
  1092.     }
  1093. a287 1
  1094.  
  1095. d291 1
  1096. a291 1
  1097.  * Lookup --
  1098. d293 2
  1099. a294 2
  1100.  *    Looks up the request ethernet address to see if there's a
  1101.  *    corresponding Inet address.
  1102. d297 1
  1103. a297 3
  1104.  *    TRUE    - the ethernet address was found and *inetPtrPtr points
  1105.  *           to the buffer containing the Inet address.
  1106.  *    FALSE    - the ethernet address was not in the table.
  1107. d300 2
  1108. a301 1
  1109.  *    None.
  1110. d306 2
  1111. a307 5
  1112. static Boolean
  1113. Lookup(etherAddr, inetAddrPtr)
  1114.     Net_EtherAddress    *etherAddr;
  1115.     Net_InetAddress    *inetAddrPtr;
  1116.  
  1117. d309 3
  1118. a311 2
  1119.     Hash_Entry    *entryPtr;
  1120.     int        etherValue[2];
  1121. d313 35
  1122. a347 4
  1123.     EtherAddrCopy(etherAddr, (short *)etherValue);
  1124.     entryPtr = Hash_FindEntry(&table, (Address) etherValue);
  1125.     if (entryPtr == (Hash_Entry  *) NULL) {
  1126.     return(FALSE);
  1127. a348 30
  1128.     bcopy ((char *) Hash_GetValue(entryPtr), (char *)inetAddrPtr,
  1129.         sizeof(Net_InetAddress));
  1130.     return(TRUE);
  1131. }
  1132.  
  1133.  
  1134.  
  1135. /*
  1136.  *----------------------------------------------------------------------
  1137.  *
  1138.  * UpdateModifyTime --
  1139.  *
  1140.  *    Checks to see if the "hosts" file has been modified.
  1141.  *
  1142.  * Results:
  1143.  *    Sets "lastModified" to most current value, if the file has
  1144.  *      been changed, and returns FALSE.  Else returns TRUE.
  1145.  *
  1146.  * Side effects:
  1147.  *    None.
  1148.  *
  1149.  *----------------------------------------------------------------------
  1150.  */ 
  1151.  
  1152. Boolean
  1153. UpdateModifyTime(hostFile, lastModified)
  1154.     char     *hostFile;
  1155.     time_t    *lastModified;
  1156. {
  1157.     struct stat        statStuff;
  1158. d350 2
  1159. a351 2
  1160.     if (stat(hostFile, &statStuff) != 0) {
  1161.     fprintf(stderr, "RARP couldn't stat hostfile \"%s\" : %s",
  1162. d353 1
  1163. a353 1
  1164.     exit(1);
  1165. d356 10
  1166. a365 5
  1167.     if (*lastModified < statStuff.st_mtime) {
  1168.     if (debug == TRUE) {
  1169.         printf("Changing host file modify time...\n");
  1170.         printf("Current modify time: %lx \n", *lastModified);
  1171.         printf("New modify time:     %lx \n\n", statStuff.st_mtime);
  1172. a366 2
  1173.     *lastModified = statStuff.st_mtime;
  1174.     return (TRUE);
  1175. d368 2
  1176. a369 31
  1177.     return (FALSE);
  1178. }
  1179.  
  1180.  
  1181.  
  1182. /*
  1183.  *----------------------------------------------------------------------
  1184.  *
  1185.  * EtherAddrCopy --
  1186.  *
  1187.  *    Copies the Ethernet address, ensuring that the last
  1188.  *      half-word (16 bits) is zero.
  1189.  *
  1190.  * Results:
  1191.  *    "toEther" contains the correct Ethernet addresss.
  1192.  *
  1193.  * Side effects:
  1194.  *    None.
  1195.  *
  1196.  *----------------------------------------------------------------------
  1197.  */
  1198.  
  1199. void
  1200. EtherAddrCopy(fromEther, toEther)
  1201.     short *fromEther;
  1202.     short *toEther;
  1203. {
  1204.     toEther[0] = fromEther[0];
  1205.     toEther[1] = fromEther[1];
  1206.     toEther[2] = fromEther[2];
  1207.     toEther[3] = 0;
  1208. a370 1
  1209.  
  1210. @
  1211.